package cn.workreport.modules.message.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.workreport.modules.common.exception.ServiceException;
import cn.workreport.modules.common.vo.PageVO;
import cn.workreport.modules.mail.service.MailTemplate;
import cn.workreport.modules.mail.util.MailUtil;
import cn.workreport.modules.message.entity.Message;
import cn.workreport.modules.message.enums.MessageTypeEnum;
import cn.workreport.modules.message.mapper.MessageMapper;
import cn.workreport.modules.message.service.IMessageService;
import cn.workreport.modules.users.entity.UserEntity;
import cn.workreport.modules.users.service.IUserService;
import cn.workreport.util.JsonResult;
import cn.workreport.util.UserChacheFromToken;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 业务接口实现类
 * </p>
 *
 * @author yyf
 * @since 2022-02-19
 */
@Slf4j
@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements IMessageService {

    private final String sendReportImagesPath = "static/images/report-imgs/ribao.jpg";

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;

    @Autowired
    private IUserService userService;

    @Autowired
    private MailTemplate mailTemplate;

    @Override
    public void wrapEntity(Message entity) {
        if (ObjectUtil.isEmpty(entity)) {
            return;
        }
        if (ObjectUtil.isNotEmpty(entity.getType())) {
            String typeLabel = entity.getType().getLabel();
            entity.setTypeLabel(typeLabel);
        }
    }

    @Override
    public PageVO<Message> pageEntity(IPage<Message> page, Wrapper<Message> queryWrapper) {
        IPage<Message> pageResult = this.page(page, queryWrapper);
        if (!ObjectUtils.isEmpty(pageResult.getRecords())) {
            pageResult.getRecords().forEach(entity -> {
                this.wrapEntity(entity);
            });
        }
        return new PageVO<>(pageResult);
    }

    @Override
    public Message getByIdEntity(Integer id) {
        Message entity = this.getById(id);
        this.wrapEntity(entity);
        return entity;
    }

    @Override
    public JsonResult<?> saveOrUpdateEntity(Message entity) {
        Message newEntity = new Message();

        BeanUtil.copyProperties(
                entity,
                newEntity,
                CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true)
        );

        boolean isSuccess = super.saveOrUpdate(newEntity);
        if (!isSuccess) {
            return JsonResult.fail("操作失败");
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> removeByIdEntity(Integer id) {
        boolean isSuccess = super.removeById(id);
        if (!isSuccess) {
            return JsonResult.fail();
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> removeByIdsEntity(List<Integer> ids) {
        for (Integer id : ids) {
            JsonResult<?> jsonResult = removeByIdEntity(id);
            if (!jsonResult.getState().equals(JsonResult.SUCCESS)) {
                return JsonResult.fail();
            }
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> setHasReadByIds(List<Integer> ids) {
        for (Integer id : ids) {
            Message message = getById(id);
            if (!ObjectUtil.isEmpty(message)) {
                message.setIsRead(true);
                boolean isSuccess = saveOrUpdate(message);
                if (!isSuccess) {
                    return JsonResult.fail();
                }
            }
        }
        return JsonResult.ok();
    }

    @Override
    public JsonResult<?> getUnReadCount() {
        UserEntity currentLoginUser = UserChacheFromToken.getUser();
        LambdaQueryWrapper<Message> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Message::getIsRead, false);
        wrapper.and((wrapperInner) -> {
            wrapperInner.eq(Message::getReceiveUserId, currentLoginUser.getId());
            wrapperInner.or();
            wrapperInner.isNull(Message::getReceiveUserId);
        });
        return JsonResult.ok(count(wrapper));
    }

    @Override
    public JsonResult<?> sendReportNoticeToUser(Integer userId) {
        if (ObjectUtils.isEmpty(userId)) {
            return JsonResult.fail("缺少参数 userId ");
        }
        UserEntity userEntity = userService.getById(userId);
        if (ObjectUtil.isEmpty(userEntity)) {
            return JsonResult.fail("该用户数据不存在");
        }
        UserEntity loginUser = UserChacheFromToken.getUser();
        Message message = new Message();
        message.setType(MessageTypeEnum.DAY_REPORT_MSG);
        String currentLoginUserName = ObjectUtil.isEmpty(loginUser.getTruename()) ? loginUser.getNickname() : loginUser.getTruename();
        String title = currentLoginUserName + "提醒您该提交日报啦";
        message.setTitle(title);
        this.sendMsgToUser(userId, message);
        // 发送邮件提醒
        if (
                ObjectUtil.isNotEmpty(userEntity.getIsOpenEmailNotation())
                        && userEntity.getIsOpenEmailNotation()
                        && ObjectUtil.isNotEmpty(userEntity.getEmail())
        ) {
            try {
                ClassPathResource classPathResource = new ClassPathResource(sendReportImagesPath);
                HashMap<String, Object> hashMap = new HashMap<>();
                String imgName = "img-01";
                hashMap.put(
                        imgName,
                        classPathResource
                );
                Map<String, String> map = new HashMap<>();
                map.put("imgName", imgName);
                map.put("userName", userEntity.getTruename());
                String content = MailUtil.ObjectToTemplate(map, "dayReport.ftl");
                mailTemplate.sendImgMail(
                        userEntity.getEmail(),
                        title,
                        content,
                        hashMap
                );
//                mailTemplate.sendSimpleMail(userEntity.getEmail(), title, "看日报");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return JsonResult.ok();
    }

    @Override
    public boolean sendMsgToUser(Integer userId, Message message) {
        if (ObjectUtil.isEmpty(userId)) {
            throw new ServiceException("缺少参数 userId");
        }
        Message msgEntity = new Message();
        BeanUtil.copyProperties(message, msgEntity);
        msgEntity.setIsRead(false);
        msgEntity.setReceiveUserId(userId);
        this.wrapEntity(msgEntity);
        // 保存消息至数据库
        if (!this.saveOrUpdate(msgEntity)) {
            throw new ServiceException("消息数据保存失败");
        }
        // 调用 convertAndSendToUser 来推送消息给用户
        simpMessagingTemplate.convertAndSendToUser(String.valueOf(userId), "/queue/info", msgEntity);
        return true;
    }

    @Override
    public boolean sendMsgToSomeUser(List<Integer> userIds, Message message) {
        if (ObjectUtil.isEmpty(userIds)) {
            throw new ServiceException("缺少参数 userIds");
        }
        for (Integer userId : userIds) {
            boolean isSuccess = sendMsgToUser(userId, message);
            if (!isSuccess) {
                return false;
            }
        }
        return true;
    }

    @Override
    public boolean sendMsgToAll(Message message) {
        Message msgEntity = new Message();
        BeanUtil.copyProperties(message, msgEntity);
        msgEntity.setReceiveUserId(null);
        msgEntity.setIsRead(false);
        // 保存消息至数据库
        boolean isSuccess = this.saveOrUpdate(msgEntity);
        if (!isSuccess) {
            return false;
        }
        simpMessagingTemplate.convertAndSend("/topic", msgEntity);
        return true;
    }
}

